package cn.tth.test.game.mysql;

import lombok.Data;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class MysqlConnectPoll {

    public static final Integer linkCount = 4;

    private List<ConnectionContext> connectionContextList = new ArrayList<>();

    public static final MysqlConnectPoll INSTANCE = new MysqlConnectPoll();

    private MysqlConnectPoll() {
        initialize();
    }

    public static MysqlConnectPoll getInstance() {
        return INSTANCE;
    }

    private void initialize(){
        for (int i = 0; i < linkCount; i++) {
            connectionContextList.add(
                    new ConnectionContext(MysqlUtils.getConnection(),ConnectionStatus.IDLE)
            );
        }
    }


    public ConnectionContext getConnection(){
        ConnectionContext connectionContext = connectionContextList.stream()
                .filter(o -> ConnectionStatus.IDLE.equals(o.getStatus()))
                .findFirst()
                .orElse(null);
        if(Objects.nonNull(connectionContext)){
            synchronized (connectionContext.getConnection()){
                if(ConnectionStatus.IDLE.equals(connectionContext.getStatus())){
                    connectionContext.setStatus(ConnectionStatus.CONNECT);
                    return connectionContext;
                }
            }
        }else {
            //丢队列，等待获取连接
        }
        return connectionContext;
    }

    public void close(ConnectionContext connectionContext) throws SQLException {
        synchronized (connectionContext.getConnection()){
            if(ConnectionStatus.CONNECT.equals(connectionContext.getStatus())){
                connectionContext.setStatus(ConnectionStatus.IDLE);
                connectionContext.getConnection().close();
            }
        }
    }

    @Data
    public static class ConnectionContext{

        public ConnectionContext(Connection connection,ConnectionStatus status){
            this.connection = connection;
            this.status = status;
        }

        private Connection connection;

        private ConnectionStatus status;
    }

    public enum ConnectionStatus {
        IDLE,
        CONNECT,
        ;
    }
}
